package com.songaw.generator.modules.globlecache.service;

import com.github.pagehelper.PageHelper;
import com.songaw.generator.common.conf.redis.RedisUtil;
import com.songaw.generator.common.constant.CacheConstant;
import com.songaw.generator.common.constant.Constant;
import com.songaw.generator.common.exception.BusinessException;
import com.songaw.generator.common.pojo.dto.PageInfoDto;
import com.songaw.generator.common.util.DateUtil;
import com.songaw.generator.modules.globlecache.entity.CacheTable;
import lombok.extern.slf4j.Slf4j;
import org.redisson.api.RLock;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.Cache;
import org.springframework.data.redis.cache.RedisCache;
import org.springframework.data.redis.cache.RedisCacheManager;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.text.ParseException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

/**
 * 全局缓存任务Service
 *
 * @author songaw
 * @date 2018/9/18 16:00
 */
@Service
@Slf4j
public class GlobleCacheService {
    @Autowired
    CacheTableService cacheTableService;
   /* @Autowired
    FundBuyingService fundBuyingService;
    @Autowired
    MoneyFundAnalysisService moneyFundAnalysisService;*/
    @Autowired
    GlobleCacheService globleCacheService;
    @Autowired
    RedisCacheManager redisCacheManager;
    public void refreshCache(CacheTable cacheTable){
        String cacheName=cacheTable.getName();
        String lockName="refreshCache:"+cacheName;

        log.info("刷新缓存 start"+cacheName);

        RLock lock = RedisUtil.getRedisson().getLock(lockName);
        log.info("试图获得锁"+lockName);
        boolean res = false;

        try {
            res = lock.tryLock(3, TimeUnit.SECONDS);
            if( res ){
                log.info("获得锁"+lockName);
                //清除缓存刷新更新时间
                updateCacheTableTime(cacheTable);
                //更新没有依赖的缓存  有依赖的缓存 会在更新没有依赖的缓存的时候更新
                switch (cacheName){
                    case CacheConstant.MONETARY_FUND_LIST:
                        //货币基金列表缓存
                        monetaryFundList(cacheTable);
                        break;
                    case CacheConstant.CACHE_ALL:
                    cacheTableService.getCacheTableList();
                    break;
                }

            }else {
                log.info("没有获得锁："+lockName);
                throw new BusinessException("正在刷新缓存"+cacheName);
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            try {
                if(res){
                    lock.unlock();
                    log.info("释放了锁:"+lockName);
                }
            } catch (Exception e2) {
                log.error(e2.getMessage());
            }
        }

        log.info("刷新缓存 end");


    }
    /**
     * 货币基金列表缓存
     */
    public void monetaryFundList(CacheTable cacheTable){
        //思路是这样 代码自己看把....

     //   List<MonetaryFundListDto> list= globleCacheService.proccessMonetaryFundList(1,10);
        //遍历调用货币基金接口
        //依赖缓存
        List<CacheTable> cacheTables = cacheTableService.getCacheTableList();
        if(CollectionUtils.isEmpty(cacheTables)){
            return;
        }
        //过滤出子缓存
        cacheTables=cacheTables.stream().filter(item->CacheConstant.MONETARY_FUND_LIST.equals(item.getParentName())&& Constant.CODE_DELETE_FLAG_0.equals(item.getDeleteFlag())).collect(Collectors.toList());
        if(CollectionUtils.isEmpty(cacheTables)){
            return;
        }
        for (CacheTable c : cacheTables) {
            //清空缓存
            updateCacheTableTime(c);
        }

        //todo 回购余额占比
        //重新加载缓存
      /*  for(MonetaryFundListDto monetaryFundListDto:list) {
            for (CacheTable c : cacheTables) {
                try {
                    switch (c.getName()) {
                        //单只货币基金QUERY_MONETARY_FUND
                        case CacheConstant.MONETARY_QUERY_MONETARY_FUND:

                            fundBuyingService.queryMonetaryFund(monetaryFundListDto.getSecurityid());
                            break;
                        //获取基金基本信息 MONETARY_GET_FD_BASICINFO_DTO
                        case CacheConstant.MONETARY_GET_FD_BASICINFO_DTO:
                            moneyFundAnalysisService.getFdBasicinfo(monetaryFundListDto.getSecurityid());
                            break;
                        //重仓持卷
                        case CacheConstant.MONETARY_GET_FD_BDDETAIL:
                            moneyFundAnalysisService.getFdBddetail(monetaryFundListDto.getSecurityid());
                            break;
                        //基金资产净值偏离
                        case CacheConstant.MONETARY_GET_FD_FUND_ASS_DEV:
                            moneyFundAnalysisService.getFdFundAssDev(monetaryFundListDto.getSecurityid());
                            break;
                        //年度收益率比较
                        case CacheConstant.MONETARY_GET_FD_ANNUALYIELD:
                            moneyFundAnalysisService.getFdAnnualyield(monetaryFundListDto.getSecurityid());
                            break;
                        //平均剩余期限分布
                        case CacheConstant.MONETARY_GET_FD_CURAVGRMMONF:
                            moneyFundAnalysisService.getFdCuravgrmmonf(monetaryFundListDto.getSecurityid());
                            break;
                        //基金规模走势
                        case CacheConstant.MONETARY_GET_FLUCTUATION_SCALE:
                            moneyFundAnalysisService.getFluctuationScale(monetaryFundListDto.getSecurityid());
                            break;
                        //七日年华收益率
                        case CacheConstant.MONETARY_GET_SEVENDAYYIELD:
                            try {
                                String beginDate = DateUtil.dateFormat(DateUtil.dateAddMonths(new Date(), -1), DateUtil.DATE_PATTERN_YYYYMMDD);
                                String endDate = DateUtil.dateFormat(DateUtil.dateAdd(new Date(), -1, false), DateUtil.DATE_PATTERN_YYYYMMDD);
                                System.out.println("近一个月:" + beginDate + "--------" + endDate);
                                moneyFundAnalysisService.getSevendayyield(monetaryFundListDto.getSecurityid(), beginDate, endDate);
                                beginDate = DateUtil.dateFormat(DateUtil.dateAddMonths(new Date(), -3), DateUtil.DATE_PATTERN_YYYYMMDD);
                                System.out.println("近三个月:" + beginDate + "--------" + endDate);
                                moneyFundAnalysisService.getSevendayyield(monetaryFundListDto.getSecurityid(), beginDate, endDate);
                            } catch (ParseException e) {
                                e.printStackTrace();
                            }
                            break;
                        //资产配置
                        case CacheConstant.MONETARY_GET_FD_ASSETPORTFOLIO:
                            moneyFundAnalysisService.getFdAssetportfolio(monetaryFundListDto.getSecurityid());
                            break;
                        //回购余额占比
                        case CacheConstant.MONETARY_GET_REPUR_RATIO:
                            moneyFundAnalysisService.getRepurRatio(monetaryFundListDto.getSecurityid());
                            break;
                    }
                }catch (Exception e){
                    e.printStackTrace();
                }

            }
        }*/


    }
    private void updateCacheTableTime(CacheTable c){
        c.setOldUpdateTime(new Date());
        cacheTableService.update(c);
        RedisCache cache = (RedisCache) redisCacheManager.getCache(c.getName());

        if(cache!=null) {
            cache.clear();
        }
    }
    public void clearCache(CacheTable c){
        Cache cache =redisCacheManager.getCache(c.getName());
        if(cache!=null) {
            cache.clear();
        }
    }
    /*public List<MonetaryFundListDto> proccessMonetaryFundList( int pageNum,int pageSize){
        MonetaryFundQueryVo monetaryFundQueryVo = new MonetaryFundQueryVo();
        monetaryFundQueryVo.setPageIndex(pageNum);
        monetaryFundQueryVo.setPageSize(pageSize);
        PageHelper.startPage(pageNum, pageSize) ;
        List<MonetaryFundListDto> list = new ArrayList<>();
        PageInfoDto<MonetaryFundListDto> pageInfoDto =fundBuyingService.queryMonetaryFundList(monetaryFundQueryVo);
        list.addAll(pageInfoDto.getList());
        if(!pageInfoDto.isIsLastPage()){
            list.addAll(globleCacheService.proccessMonetaryFundList(pageInfoDto.getNextPage(),pageSize));
        }
        return list;
    }*/




}
